package com.xunua.NaoZiKongBai.Fragments.ShouYe;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.internal.NavigationMenu;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;
import com.gyf.immersionbar.ImmersionBar;
import com.trello.rxlifecycle2.components.support.RxFragment;
import com.xunua.NaoZiKongBai.Bean.ApiResponse.NewsType;
import com.xunua.NaoZiKongBai.Bean.EventBus.RefreshEvent;
import com.xunua.NaoZiKongBai.Constant;
import com.xunua.NaoZiKongBai.R;
import com.xunua.NaoZiKongBai.Utils.log;
import com.xunua.NaoZiKongBai.api.RetrofitApiService;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import cn.bmob.v3.helper.BmobNative;
import cn.jzvd.JzvdStd;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class ShouYeFragment extends RxFragment {
    @BindView(R.id.shouye_tb)
    TabLayout shouyetb;
    @BindView(R.id.shouye_vp)
    ViewPager shouyevp;
    @BindView(R.id.shouye_statur)
    TextView shouyeStatur;
    private Unbinder unbinder;
    //    private MMKV mmkv = MMKV.mmkvWithID("newsType");
    private List<NewsTypeBean> newsTypeList;


    /**
     * 获取newstype
     */
    // 设置变量
    // 可重试次数
    private int maxConnectCount = Integer.MAX_VALUE;
    // 当前已重试次数
    private int currentRetryCount = 0;
    // 重试等待时间
    private int waitRetryTime = 0;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_shou_ye, container, false);
        unbinder = ButterKnife.bind(this, view);
        EventBus.getDefault().register(this);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initnewsType();
    }

    private void initViewPager() {
        shouyevp.setAdapter(new NewsPagerAdapter(getFragmentManager()));
        shouyetb.setupWithViewPager(shouyevp);//关联viewpager和tablayout
        shouyetb.getTabAt(0).select();//默认选择一个标签
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
        EventBus.getDefault().unregister(this);
    }

    private void initnewsType() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.wanAndroid_baseurl)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        retrofit.create(RetrofitApiService.class).getNewsType(Constant.getWanAndroidApiKey())
                .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(@NonNull Observable<Throwable> throwableObservable) throws Exception {
                        // 参数Observable<Throwable>中的泛型 = 上游操作符抛出的异常，可通过该条件来判断异常的类型
                        return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(@NonNull Throwable throwable) throws Exception {

                                // 输出异常信息
//                                Log.d(TAG,  "发生异常 = "+ throwable.toString());

                                /**
                                 * 需求1：根据异常类型选择是否重试
                                 * 即，当发生的异常 = 网络异常 = IO异常 才选择重试
                                 */
                                if (throwable instanceof IOException) {

//                                    Log.d(TAG,  "属于IO异常，需重试" );

                                    /**
                                     * 需求2：限制重试次数
                                     * 即，当已重试次数 < 设置的重试次数，才选择重试
                                     */
                                    if (currentRetryCount < maxConnectCount) {

                                        // 记录重试次数
                                        currentRetryCount++;
//                                        Log.d(TAG,  "重试次数 = " + currentRetryCount);

                                        /**
                                         * 需求2：实现重试
                                         * 通过返回的Observable发送的事件 = Next事件，从而使得retryWhen（）重订阅，最终实现重试功能
                                         *
                                         * 需求3：延迟1段时间再重试
                                         * 采用delay操作符 = 延迟一段时间发送，以实现重试间隔设置
                                         *
                                         * 需求4：遇到的异常越多，时间越长
                                         * 在delay操作符的等待时间内设置 = 每重试1次，增多延迟重试时间1s
                                         */
                                        // 设置等待时间
                                        waitRetryTime = 1000 + currentRetryCount * 1000;
                                        waitRetryTime = 3000;//我这里修改为固定为三秒重连一次
//                                        Log.d(TAG,  "等待时间 =" + waitRetryTime);
                                        return Observable.just(1).delay(waitRetryTime, TimeUnit.MILLISECONDS);//等于onnext(1)
                                    } else {
                                        // 若重试次数已 > 设置重试次数，则不重试
                                        // 通过发送error来停止重试（可在观察者的onError（）中获取信息）
                                        return Observable.error(new Throwable("重试次数已超过设置次数 = " + currentRetryCount + "，即 不再重试"));
                                    }
                                }

                                // 若发生的异常不属于I/O异常，则不重试
                                // 通过返回的Observable发送的事件 = Error事件 实现（可在观察者的onError（）中获取信息）
                                else {
                                    return Observable.error(new Throwable("发生了非网络异常（非I/O异常）"));
                                }
                            }
                        });
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<NewsType>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(NewsType newsType) {
                        newsTypeList = new ArrayList<>();
                        for (NewsType.DataBean data :
                                newsType.getData()) {
                            NewsTypeBean newsTypeBean = new NewsTypeBean(data.getTypeName(), data.getTypeId());
                            if (newsTypeBean.getTypename().equals("热点")) {
                                newsTypeList.add(0, newsTypeBean);
                            } else if (newsTypeBean.getTypename().equals("头条")) {
                                //移除头条
//                                newsTypeList.add(0, newsTypeBean);
                            } else if (newsTypeBean.getTypename().equals("小视频")) {
                                //不添加小视频，考虑把小视频 单独拿出来弄。   编号526
//                            log.e("小视频的编号"+newsTypeBean.getTypeid());
                            } else if (newsTypeBean.getTypename().equals("视频")) {
                                newsTypeList.add(0, newsTypeBean);
                            } else {
                                newsTypeList.add(newsTypeBean);
                            }
                        }
                        initViewPager();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Snackbar.make(getView(), ""+e, Snackbar.LENGTH_LONG).show();
                        log.e("接口信息获取"+e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
        shouyetb.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                if (!tab.getText().equals("视频")) {
                    JzvdStd.releaseAllVideos();
                }
                TextView textView = new TextView(getContext());
                textView.setText(tab.getText());
                textView.setTextSize(25);
                textView.setTextColor(getResources().getColor(R.color.colorWhite));
                tab.setCustomView(null);//避免某种神仙操作
                tab.setCustomView(textView);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                tab.setCustomView(null);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }


    private class NewsPagerAdapter extends FragmentStatePagerAdapter {

        public NewsPagerAdapter(@NonNull FragmentManager fm) {
            super(fm);
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            return NewsFragment.newInstance(newsTypeList.get(position));
        }

        //TabLayout会根据当前page的title自动绑定tab
        @Override
        public CharSequence getPageTitle(int position) {
            return newsTypeList.get(position).getTypename();
        }

        @Override
        public int getCount() {
            return newsTypeList.size();
        }

//        int chidCount=0;//view pager的页数
//        //当viewpager页数发生变化时，必须要重写这两个方法才能更新数据。
//        @Override
//        public void notifyDataSetChanged() {
//            super.notifyDataSetChanged();
//            this.chidCount=getCount();
//            super.notifyDataSetChanged();//更新数据
//        }
//        @Override
//        public int getItemPosition(@NonNull Object object) {
//            if (chidCount > 0) {
//                chidCount--;
//                return POSITION_NONE;  //有疑惑
//            }
//            return super.getItemPosition(object);
//        }
    }

    protected class NewsTypeBean {
        private String typename;
        private int typeid;

        public NewsTypeBean(String typename, int typeid) {
            this.typename = typename;
            this.typeid = typeid;
        }

        public String getTypename() {
            return typename;
        }

        public void setTypename(String typename) {
            this.typename = typename;
        }

        public int getTypeid() {
            return typeid;
        }

        public void setTypeid(int typeid) {
            this.typeid = typeid;
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void Parentrefresh(String event) {
        if (event.equals("刷新新闻")) {
            if (shouyetb.getTabAt(shouyetb.getSelectedTabPosition()).getText().toString()!=null)
            EventBus.getDefault().post(new RefreshEvent(shouyetb.getTabAt(shouyetb.getSelectedTabPosition()).getText().toString()));
        }
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            initStatur();
        }
    }

    private void initStatur() {
        ImmersionBar.with(this)
                .statusBarView(shouyeStatur)
                .keyboardEnable(true)//解决软键盘与底部输入框冲突问题
                .statusBarDarkFont(false)//状态栏字体颜色
                .navigationBarColor(R.color.navigationBarcolor)//导航栏颜色，不写默认黑色
                .navigationBarDarkIcon(true)//导航栏图标是深色，不写默认为亮色
                .init();//沉浸状态栏
    }
}
